#!/bin/sh
set -e

TESTDIR="$(readlink -f "$(dirname "$0")")"
. "$TESTDIR/framework"

setupenvironment
configarchitecture "i386"

insertinstalledpackage 'foobar' 'all' '1'

buildaptarchive
setupflataptarchive

STATUS=$(readlink -f rootdir/var/lib/dpkg/status)
APTARCHIVE=$(readlink -f aptarchive)

testequalpolicy() {
	local SP="$1"
	local AP="$2"
	shift 2
	testsuccessequal "Package files:
 $(printf '%3s' "$SP") ${STATUS}
     release a=now
 $(printf '%3s' "$AP") file:${APTARCHIVE}  Packages
     release c=
Pinned packages:" aptcache policy "$@"
}

testglobalpolicy() {
	aptgetupdate

	testequalpolicy 100 500
	testequalpolicy 990 500 -t now

	sed -i aptarchive/Release -e 1i"NotAutomatic: yes"
	aptgetupdate

	testequalpolicy 100 1 -o Test=NotAutomatic
	testequalpolicy 990 1 -o Test=NotAutomatic -t now

	sed -i aptarchive/Release -e 1i"ButAutomaticUpgrades: yes"
	aptgetupdate

	testequalpolicy 100 100 -o Test=ButAutomaticUpgrades
	testequalpolicy 990 100 -o Test=ButAutomaticUpgrades -t now

	sed -i aptarchive/Release -e 's#NotAutomatic: yes#NotAutomatic: no#' -e '/ButAutomaticUpgrades: / d'
	aptgetupdate

	testequalpolicy 100 500 -o Test=Automatic
	testequalpolicy 990 500 -o Test=Automatic -t now

	sed -i aptarchive/Release -e '/NotAutomatic: / d' -e '/ButAutomaticUpgrades: / d'
}

msgmsg 'Test with not signed archive'
aptgetupdate() {
	rm -rf rootdir/var/lib/apt
	testwarning aptget update  --allow-insecure-repositories
}
testglobalpolicy

msgmsg 'Test with signed but no key in trusted'
aptgetupdate() {
	rm -rf rootdir/var/lib/apt
	signreleasefiles 'Marvin Paranoid'
	testwarning aptget update  --allow-insecure-repositories
}
testglobalpolicy

# much the same tests will be executed below in more detail again for this one
msgmsg 'Test with signed and valid key'
aptgetupdate() {
	rm -rf rootdir/var/lib/apt
	signreleasefiles 'Joe Sixpack'
	testsuccess aptget update
}
testglobalpolicy

msgmsg 'Test with specific packages'

buildsimplenativepackage "coolstuff" "all" "1.0" "stable"
buildsimplenativepackage "coolstuff" "all" "2.0~bpo1" "backports"

setupaptarchive

testsuccessequal "coolstuff:
  Installed: (none)
  Candidate: 2.0~bpo1
  Version table:
     2.0~bpo1 500
        500 file:${APTARCHIVE} backports/main all Packages
     1.0 500
        500 file:${APTARCHIVE} stable/main all Packages" apt policy '^cool.*'

testequalpolicycoolstuff() {
	local INSTALLED="${1:-(none)}"
	local CANDIDATE="${2:-(none)}"
	local AB="$3"
	local AS="$4"
	local PB="$5"
	local IS=""
	local IB=""
	local SB=""
	local SS=""
	[ "$1" = "2.0~bpo1" ] && IB="***" && SB="
        100 $STATUS" || IB="   "
	[ "$1" = "1.0" ] && IS="***" && SS="
        100 $STATUS" || IS="   "
	local BPO1ARCHIVE=""
	local BPO2ARCHIVE=""
	if [ ! "$7" = "2.0~bpo2" ]; then
		BPO1PIN="$AB"
		BPO1ARCHIVE="        $(printf '%3s' "$AB") file:${APTARCHIVE} backports/main all Packages"
	else
		BPO2ARCHIVE="
     2.0~bpo2 $AB
        $(printf '%3s' "$AB") file:${APTARCHIVE} backports/main all Packages"
		SB="$(echo "$SB" | tail -n 1)"
		shift
	fi
	shift 6
	testsuccessequal "coolstuff:
  Installed: $INSTALLED
  Candidate: $CANDIDATE
  Version table:${BPO2ARCHIVE}
 $IB 2.0~bpo1 $PB
${BPO1ARCHIVE}$SB
 $IS 1.0 $AS
        $(printf '%3s' "$AS") file:${APTARCHIVE} stable/main all Packages$SS" \
		aptcache policy coolstuff -o Policy=${INSTALLED}-${CANDIDATE}-${AB}-${AS}-${PB} $*
}

testequalpolicycoolstuff "" "2.0~bpo1" 500 500 500 ""
testequalpolicycoolstuff "" "1.0" 500 990 500 "" -t stable
testequalpolicycoolstuff "" "2.0~bpo1" 990 500 990 "" -t backports
echo "Package: *
Pin: release n=backports
Pin-Priority: 200" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "1.0" 200 500 200 "" -o Test=GlobalPin
testequalpolicycoolstuff "" "1.0" 200 990 200 "" -o Test=GlobalPin -t stable
testequalpolicycoolstuff "" "2.0~bpo1" 990 500 990 "" -o Test=GlobalPin -t backports
echo "Package: *
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 600 500 600 "" -o Test=GlobalPin
testequalpolicycoolstuff "" "1.0" 600 990 600 "" -o Test=GlobalPin -t stable
echo "Package: cool*
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 500 500 600 "" -o Test=GlobPin
testequalpolicycoolstuff "" "1.0" 500 990 600 "" -o Test=GlobPin -t stable
echo "Package: /cool.*/
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 500 500 600 "" -o Test=RegexPin
testequalpolicycoolstuff "" "1.0" 500 990 600 "" -o Test=RegexPin -t stable
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 200" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "1.0" 500 500 200 "2.0~bpo1" -o Test=PackagePin
testequalpolicycoolstuff "" "1.0" 990 500 200 "2.0~bpo1" -o Test=PackagePin -t backports
testequalpolicycoolstuff "" "1.0" 500 990 200 "2.0~bpo1" -o Test=PackagePin -t stable
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 500 500 600 "2.0~bpo1" -o Test=PackagePin
testequalpolicycoolstuff "" "1.0" 500 990 600 "2.0~bpo1" -o Test=PackagePin -t stable
testequalpolicycoolstuff "" "2.0~bpo1" 990 500 600 "2.0~bpo1" -o Test=PackagePin -t backports

echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: -1" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "1.0" 500 500 -1 "2.0~bpo1" -o Test=PackagePin
testequalpolicycoolstuff "" "1.0" 990 500 -1 "2.0~bpo1" -o Test=PackagePin -t backports
testequalpolicycoolstuff "" "1.0" 500 990 -1 "2.0~bpo1" -o Test=PackagePin -t stable

rm rootdir/etc/apt/preferences
sed -i aptarchive/dists/backports/Release -e 1i"NotAutomatic: yes"
signreleasefiles
aptgetupdate

testequalpolicycoolstuff "" "1.0" 1 500 1 "" -o Test=NotAutomatic
testequalpolicycoolstuff "" "1.0" 1 990 1 "" -o Test=NotAutomatic -t stable
testequalpolicycoolstuff "" "2.0~bpo1" 990 500 990 "" -o Test=NotAutomatic -t backports
echo "Package: *
Pin: release n=backports
Pin-Priority: 200" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "1.0" 200 500 200 "" -o Test=NotAutomatic
echo "Package: *
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 600 500 600 "" -o Test=NotAutomatic
testequalpolicycoolstuff "" "1.0" 600 990 600 "" -o Test=NotAutomatic -t stable
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 200" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "1.0" 1 500 200 "2.0~bpo1" -o Test=NotAutomatic
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 1 500 600 "2.0~bpo1" -o Test=NotAutomatic
testequalpolicycoolstuff "" "2.0~bpo1" 990 500 600 "2.0~bpo1" -o Test=NotAutomatic -t backports
testequalpolicycoolstuff "" "1.0" 1 990 600 "2.0~bpo1" -o Test=NotAutomatic -t stable

rm rootdir/etc/apt/preferences
sed -i aptarchive/dists/backports/Release -e 1i"ButAutomaticUpgrades: yes"
signreleasefiles
aptgetupdate

testequalpolicycoolstuff "" "1.0" 100 500 100 "" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "" "1.0" 100 990 100 "" -o Test=ButAutomaticUpgrades -t stable
testequalpolicycoolstuff "" "2.0~bpo1" 990 500 990 "" -o Test=ButAutomaticUpgrades -t backports
echo "Package: *
Pin: release n=backports
Pin-Priority: 200" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "1.0" 200 500 200 "" -o Test=ButAutomaticUpgrades
echo "Package: *
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 600 500 600 "" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "" "1.0" 600 990 600 "" -o Test=ButAutomaticUpgrades -t stable
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 200" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "1.0" 100 500 200 "2.0~bpo1" -o Test=ButAutomaticUpgrades
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 600" > rootdir/etc/apt/preferences
testequalpolicycoolstuff "" "2.0~bpo1" 100 500 600 "2.0~bpo1" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "" "2.0~bpo1" 990 500 600 "2.0~bpo1" -o Test=ButAutomaticUpgrades -t backports
testequalpolicycoolstuff "" "1.0" 100 990 600 "2.0~bpo1" -o Test=ButAutomaticUpgrades -t stable

rm rootdir/etc/apt/preferences
testsuccess aptget install coolstuff -y
testequalpolicycoolstuff "1.0" "1.0" 100 500 100 "" -o Test=ButAutomaticUpgrades
testsuccess aptget dist-upgrade -y
testequalpolicycoolstuff "1.0" "1.0" 100 500 100 "" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "1.0" "1.0" 100 990 100 "" -o Test=ButAutomaticUpgrades -t stable
testequalpolicycoolstuff "1.0" "2.0~bpo1" 990 500 990 "" -o Test=ButAutomaticUpgrades -t backports

testsuccess aptget install coolstuff -t backports -y
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 100 500 100 "" -o Test=ButAutomaticUpgrades
testsuccess aptget dist-upgrade -y
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 100 500 100 "" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 100 990 100 "" -o Test=ButAutomaticUpgrades -t stable
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 990 500 990 "" -o Test=ButAutomaticUpgrades -t backports

rm incoming/backports.main.pkglist incoming/backports.main.srclist
buildsimplenativepackage "coolstuff" "all" "2.0~bpo2" "backports"
buildsimplenativepackage "hotstuff" "all" "1.0" "backports"
setupaptarchive --no-update

sed -i aptarchive/dists/backports/Release -e 1i"NotAutomatic: yes"
signreleasefiles
aptgetupdate

testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 1 500 100 "" "2.0~bpo2" -o Test=NotAutomatic
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 1 990 100 "" "2.0~bpo2" -o Test=NotAutomatic -t stable
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 990 500 100 "" "2.0~bpo2" -o Test=NotAutomatic -t backports

sed -i aptarchive/dists/backports/Release -e 1i"ButAutomaticUpgrades: yes"
signreleasefiles
aptgetupdate

testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 100 500 100 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 100 990 100 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades -t stable
testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 990 500 100 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades -t backports


tmppath="$(readlink -f .)"

# Check 16-bit integers
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 32767
" > rootdir/etc/apt/preferences

testsuccess aptget install -s coolstuff -o PinPriority=32767

echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: -32768
" > rootdir/etc/apt/preferences
testsuccess aptget install -s coolstuff -o PinPriority=-32768

# Check for 32-bit integers
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 32768
" > rootdir/etc/apt/preferences

testfailureequal "Reading package lists...
E: ${tmppath}/rootdir/etc/apt/preferences: Value 32768 is outside the range of valid pin priorities (-32768 to 32767)" \
 aptget install -s coolstuff -o PinPriority=32768


echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: -32769
" > rootdir/etc/apt/preferences

testfailureequal "Reading package lists...
E: ${tmppath}/rootdir/etc/apt/preferences: Value -32769 is outside the range of valid pin priorities (-32768 to 32767)" \
 aptget install -s coolstuff -o PinPriority=-32769

# Check for 64-bit integers

echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 2147483648
" > rootdir/etc/apt/preferences

testfailureequal "Reading package lists...
E: Cannot convert 2147483648 to integer: out of range
E: ${tmppath}/rootdir/etc/apt/preferences: Value 2147483648 is outside the range of valid pin priorities (-32768 to 32767)" \
 aptget install -s coolstuff -o PinPriority=2147483648

# Check that short-max/min is a valid pin
currentpin() {
echo "Package: *
Pin: release n=backports
Pin-Priority: $1
" > rootdir/etc/apt/preferences
testsuccessequal "coolstuff:
  Installed: 2.0~bpo1
  Candidate: $2
  Version table:
     2.0~bpo2 ${3:-$1}
       ${3:-$1} file:${tmppath}/aptarchive backports/main all Packages
 *** 2.0~bpo1 100
        100 ${tmppath}/rootdir/var/lib/dpkg/status
     1.0 500
        500 file:${tmppath}/aptarchive stable/main all Packages" apt policy coolstuff
}
currentpin '32767' '2.0~bpo2'
currentpin '-32768' '2.0~bpo1' '-32767'
currentpin '-32767' '2.0~bpo1' '-32767'

# Check for 0
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 0
" > rootdir/etc/apt/preferences

testfailureequal "Reading package lists...
E: No priority (or zero) specified for pin" \
 aptget install -s coolstuff -o PinPriority=0

# Check with comments
echo "#Package: coolstuff
#Pin: release n=backports
#Pin-Priority: 0

# Test

Package: coolstuff
Pin: release n=backports
#Pin: release n=unstable
#Pin-Priority: 999
Pin-Priority: 999
#Pin-Priority: 999" > rootdir/etc/apt/preferences

testsuccessequal "coolstuff:
  Installed: 2.0~bpo1
  Candidate: 2.0~bpo2
  Version table:
     2.0~bpo2 999
        100 file:${tmppath}/aptarchive backports/main all Packages
 *** 2.0~bpo1 100
        100 ${tmppath}/rootdir/var/lib/dpkg/status
     1.0 500
        500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff


# Check for override pins

# Normal pins: First one wins
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 990

Package: coolstuff
Pin: release n=backports
Pin-Priority: 991
" > rootdir/etc/apt/preferences

testsuccessequal "coolstuff:
  Installed: 2.0~bpo1
  Candidate: 2.0~bpo2
  Version table:
     2.0~bpo2 990
        100 file:${tmppath}/aptarchive backports/main all Packages
 *** 2.0~bpo1 100
        100 ${tmppath}/rootdir/var/lib/dpkg/status
     1.0 500
        500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff


echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: 990

Package: *
Pin: release n=backports
Pin-Priority: never
" > rootdir/etc/apt/preferences

testsuccessequal "coolstuff:
  Installed: 2.0~bpo1
  Candidate: 2.0~bpo1
  Version table:
     2.0~bpo2 -32768
       -32768 file:${tmppath}/aptarchive backports/main all Packages
 *** 2.0~bpo1 100
        100 ${tmppath}/rootdir/var/lib/dpkg/status
     1.0 500
        500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff


msgmsg "Check that local-only versions can be pinned correctly (LP: #1821308)"
echo "Package: coolstuff
Pin: version 2.0~bpo1
Pin-Priority: 1000" > rootdir/etc/apt/preferences
testsuccessequal "coolstuff:
  Installed: 2.0~bpo1
  Candidate: 2.0~bpo1
  Version table:
     2.0~bpo2 100
        100 file:${tmppath}/aptarchive backports/main all Packages
 *** 2.0~bpo1 1000
        100 ${tmppath}/rootdir/var/lib/dpkg/status
     1.0 500
        500 file:${tmppath}/aptarchive stable/main all Packages" aptcache policy coolstuff

# Check for 0
echo "Package: coolstuff
Pin: release n=backports
Pin-Priority: never
" > rootdir/etc/apt/preferences

testfailureequal "Reading package lists...
E: ${tmppath}/rootdir/etc/apt/preferences: The special 'Pin-Priority: never' can only be used for 'Package: *' records" \
 aptget install -s coolstuff -o PinPriority=0

# Test multiple packages
echo "Package: coolstuff hotstuff
Pin: release n=backports
Pin-Priority: 600
" > rootdir/etc/apt/preferences

testsuccessequal "coolstuff:
  Installed: 2.0~bpo1
  Candidate: 2.0~bpo2
  Version table:
     2.0~bpo2 600
        100 file:${tmppath}/aptarchive backports/main all Packages
 *** 2.0~bpo1 100
        100 ${tmppath}/rootdir/var/lib/dpkg/status
     1.0 500
        500 file:${tmppath}/aptarchive stable/main all Packages
hotstuff:
  Installed: (none)
  Candidate: 1.0
  Version table:
     1.0 600
        100 file:${tmppath}/aptarchive backports/main all Packages" aptcache policy coolstuff hotstuff

echo "Package: c?ol*ff /hot[st]+uff/
Pin: release n=backports
Pin-Priority: 600
" > rootdir/etc/apt/preferences

testsuccessequal "coolstuff:
  Installed: 2.0~bpo1
  Candidate: 2.0~bpo2
  Version table:
     2.0~bpo2 600
        100 file:${tmppath}/aptarchive backports/main all Packages
 *** 2.0~bpo1 100
        100 ${tmppath}/rootdir/var/lib/dpkg/status
     1.0 500
        500 file:${tmppath}/aptarchive stable/main all Packages
hotstuff:
  Installed: (none)
  Candidate: 1.0
  Version table:
     1.0 600
        100 file:${tmppath}/aptarchive backports/main all Packages" aptcache policy coolstuff hotstuff
